home *** CD-ROM | disk | FTP | other *** search
/ Clickx 115 / Clickx 115.iso / software / tools / windows / tails-i386-0.16.iso / live / filesystem.squashfs / usr / bin / foomatic-ppdfile < prev    next >
Encoding:
Text File  |  2010-09-16  |  9.4 KB  |  312 lines

  1. #!/usr/bin/perl
  2. # -*- perl -*-
  3.  
  4. # Foomatic PPD file generator for manual PPD generation (via "-p",
  5. # "-d", "-A", and "-P" command line options) or for automatic
  6. # on-the-fly PPD generation by CUPS 1.2 or newer (via "cat" and "list"
  7. # command line options).
  8.  
  9. use Foomatic::Defaults;
  10. use Foomatic::DB;
  11. use Getopt::Std;
  12. use Data::Dumper;
  13. #use strict;
  14.  
  15. my $debug = 0;
  16.  
  17. # Use program name as the first part of the PPD URI for CUPS (should be 
  18. # "foomatic").
  19. $0 =~ m!/([^/]+)\s*$!;
  20. my $progname = ($1 || $0);
  21.  
  22. # Default settings for listing PPDs by cups-driverd
  23.  
  24. # List only the PPD file with the reconmmended driver for each printer
  25. # and do not show "(recommended)" in the CUPS web interface. This mode
  26. # makes CUPS setup with the web interface very easy for beginners.
  27. # This can be set by "OnlyRecommended Yes" or "OnlyRecommended No" in
  28. # /etc/cups/foomatic.conf
  29. my $onlyrecommended = 0;
  30. # The Foomatic database does not only generate PPD files from Foomatic
  31. # XML data but also of ready-made PPDs mainly from printer manufacturers
  32. # for their PostScript printers. As these PPDs are often also linked to
  33. # the directories in which CUPS links directly to PPD files, duplicate
  34. # listing of these PPDs by CUPS would result. Therefore we suppress
  35. # listing the ready-made PPDs. This behaviour can be changed by using
  36. # "ListReadyMadePPDs Yes" or "ListReadyMadePPDs No" in
  37. # /etc/cups/foomatic.conf
  38. my $listreadymadeppds = 0;
  39. help() if !@ARGV;
  40. #my ($opt_h, $opt_d, $opt_p, $opt_A, $opt_P, $opt_w);
  41. getopts("AP:d:p:hwt:");
  42. help() if $opt_h;
  43. my $drv = $opt_d;
  44. my $poid   = $opt_p;
  45. my $showall   = $opt_A;
  46. my $showmatch   = $opt_P;
  47. help() if ($#ARGV > 1) && !($poid);
  48.  
  49. if ($ARGV[0] =~ /^list$/i) {
  50.     # List all available PPD files (format for cups-driverd)
  51.     cupslistppds();
  52. } elsif ($ARGV[0] =~ /^cat$/i) {
  53.     # Generate and return the selected PPD file (cups-driverd command line)
  54.     generateppd($ARGV[1]);
  55. } elsif ($showall or $showmatch) {
  56.     # List all PPD files or files matching regexp (manual operation)
  57.     foomaticlistppds($showmatch);
  58. } elsif ($poid) {
  59.     # Generate and return the selected PPD file (manual operation)
  60.     generateppd($poid, $drv);
  61. } else {
  62.     help();
  63. }
  64.  
  65. exit(0);
  66.  
  67. sub cupslistppds {
  68.  
  69.     # Read configuration in /etc/cups/foomatic.conf
  70.     my $conffilename;
  71.     if (my $cupsserverroot = $ENV{CUPS_SERVERROOT}) {
  72.         $conffilename = "$cupsserverroot/foomatic.conf";
  73.     } else {
  74.         $conffilename = "/etc/cups/foomatic.conf";
  75.     }
  76.     my $onlyrecommended = 0;
  77.     my $listreadymadeppds = 0;
  78.     if (-r $conffilename and
  79.     open CONF, "< $conffilename") {
  80.     while (my $line = <CONF>) {
  81.         chomp $line;
  82.         if ($line =~
  83.         /^\s*OnlyRecommended\s+(Yes|On|True|1)\s*$/i) {
  84.         $onlyrecommended = 1;
  85.         } elsif ($line =~
  86.              /^\s*OnlyRecommended\s+(No|Off|False|0)\s*$/i) {
  87.         $onlyrecommended = 0;
  88.         }
  89.         if ($line =~
  90.         /^\s*ListReadyMadePPDs\s+(Yes|On|True|1)\s*$/i) {
  91.         $listreadymadeppds = 1;
  92.         } elsif ($line =~
  93.              /^\s*ListReadyMadePPDs\s+(No|Off|False|0)\s*$/i) {
  94.         $listreadymadeppds = 0;
  95.         }
  96.     }
  97.     close CONF;
  98.     }
  99.  
  100.     my $db = Foomatic::DB->new();
  101.     $db->get_overview(1, 1 + $listreadymadeppds);
  102.  
  103.     for my $printer (@{$db->{'overview'}}) {
  104.     my $poid = $printer->{'id'};
  105.     my $make = $printer->{'make'};
  106.     my $model = $printer->{'model'};
  107.     my $recdriver = $printer->{'driver'};
  108.     my @drivers = @{$printer->{'drivers'}};
  109.     my $id = $printer->{'ieee'};
  110.  
  111.     # No drivers => No PPDs
  112.     next if $#drivers < 0;
  113.  
  114.     # Put the reconmmended driver to the beginning of list, as CUPS
  115.     # probably will take the first PPD which matches the printer model
  116.     my @sorteddrivers;
  117.     if (Foomatic::DB::member($recdriver, @drivers)) {
  118.         # Valid entry for the recommended driver
  119.         push(@sorteddrivers, $recdriver);
  120.         if (!$onlyrecommended) {
  121.         foreach my $driver (@drivers) {
  122.             push(@sorteddrivers, $driver) if $driver ne $recdriver;
  123.         }
  124.         }
  125.     } else {
  126.         # Invalid entry for the recommended driver
  127.         next if $onlyrecommended;
  128.         undef $recdriver;
  129.         @sorteddrivers = @drivers;
  130.     }
  131.  
  132.     # Go through all the drivers and list the PPD entries
  133.     foreach my $driver (@sorteddrivers) {
  134.         # Get PPD header data from the PPD file generator
  135.         my ($ieee1284,$pnpmake,$pnpmodel,$filename,$longname,
  136.         $drivername,$nickname,$modelname) =
  137.             Foomatic::DB::getppdheaderdata($printer, $driver, 
  138.                            ($onlyrecommended ? '' :
  139.                             $printer->{'driver'}));
  140.         print "\"$progname:$printer->{'id'}-$driver.ppd\" en \"$make\" \"$nickname\" \"$ieee1284\"\n";
  141.     }
  142.     }
  143. }
  144.  
  145. sub foomaticlistppds {
  146.  
  147.     my ($match) = @_;
  148.  
  149.     my $db = Foomatic::DB->new();
  150.     $db->get_overview();
  151.     my @drivers = $db->get_driverlist();
  152.  
  153.     for my $printer (@{$db->{'overview'}}) {
  154.     my $pr = $printer->{'make'};
  155.     my $model = $printer->{'model'};
  156.     my $name = "$pr $model";
  157.     my $driver = ($printer->{'driver'} || "No Default Driver");
  158.     my $dlist = "";
  159.     my $dcount = 0;
  160.     if( $printer->{'drivers'} ){
  161.         $dcount = @{$printer->{'drivers'}};
  162.         for my $d (@{$printer->{'drivers'}}) {
  163.         $dlist .= "$d ";
  164.         }
  165.     }
  166.     if (not $match or "$name" =~ m{$match}o) {
  167.         print "$name Id='$printer->{'id'}' Driver='$driver'";
  168.         if ($dcount > 1){
  169.         print " CompatibleDrivers='$dlist'";
  170.         }
  171.         print "\n";
  172.     }
  173.     }
  174. }
  175.  
  176. sub generateppd {
  177.  
  178.     my ($ppduri, $driver) = @_;
  179.     my $poid;
  180.  
  181.     my $db = Foomatic::DB->new();
  182.     my $printer;
  183.     my @drivers = $db->get_driverlist();
  184.  
  185.     if ($ppduri =~ /^$progname:(.*)\.ppd$/) {
  186.     # cups-driverd operation
  187.     # We try to split between printer name and driver name at all
  188.     # dashes in the PPD file name, as some drivers (ex. Gutenprint)
  189.     # have dashes in their names.
  190.     my $ppdname = $1;
  191.     my @poidcomponents = split(/-/, $ppdname);
  192.     my @drivercomponents = ();
  193.     my @printers = $db->get_printerlist();
  194.     while ($#poidcomponents > 1) {
  195.         unshift(@drivercomponents, pop(@poidcomponents));
  196.         $driver = join('-', @drivercomponents);
  197.         $printer = join('-', @poidcomponents);
  198.         next if (!Foomatic::DB::member($driver, @drivers) and
  199.              !Foomatic::DB::member($printer, @printers));
  200.         $poid = join('-', @poidcomponents);
  201.         last;
  202.     }
  203.     die "ERROR: Could not determine driver name for $ppdname.ppd!\n"
  204.         if( !$poid );
  205.     } else {
  206.     # manual operation
  207.     $poid = $ppduri;
  208.     }
  209.  
  210.     # If the user supplies an old numerical printer ID, translate it to
  211.     # a new clear-text ID
  212.     $poid = Foomatic::DB::translate_printer_id($poid);
  213.  
  214.     my $lcname = lc( $poid );
  215.     my $pentry = $db->get_printer($poid);
  216.     if (!$pentry || ($pentry->{'noxmlentry'} != 0)) {
  217.     $pentry = undef;
  218.     $db->get_overview();
  219.     for $printer (@{$db->{'overview'}}) {
  220.         my $name = lc( $printer->{'id'} );
  221.         print STDERR "DEBUG2: $progname: compare '$lcname' to '$name'\n" if $debug;
  222.         if( $name eq $lcname ){
  223.         $pentry = $printer;
  224.         $poid = $pentry->{'id'};
  225.         print STDERR "DEBUG: $progname: Using printer entry '$poid'\n" if $debug;
  226.         last;
  227.         }
  228.     }
  229.     }
  230.  
  231.     print STDERR "DEBUG: Printer '$poid' not found!\n" if ($debug && not defined $pentry );
  232.     print STDERR "DEBUG: $progname: Found $pentry->{id}\nDEBUG2: $progname: " .
  233.     join ("\nDEBUG2: $progname: ", split(/\n/, Dumper($pentry))) .
  234.     "\n" if $debug;
  235.     
  236.     if (!$driver || ($driver =~ /(default|recommended)/i)) {
  237.     $driver = $pentry->{'driver'};
  238.     if( not defined( $driver ) ){
  239.         die "ERROR: $progname: Printer '$poid' does not have default driver!\n";
  240.     }
  241.     }
  242.     
  243.     my @drvlist = $db->get_drivers_for_printer($poid);
  244.     my $found = 0;
  245.     for my $d (@drvlist) {
  246.     last if ($found = ($driver eq $d));
  247.     }
  248.     if ( not $found ) {
  249.     warn "ERROR: $progname: Printer '$poid' and driver '$driver' are not compatible\n";
  250.     }
  251.     $found = 0;
  252.     for my $d (@drivers) {
  253.     last if ($found = ($driver eq $d));
  254.     }
  255.     if ( not $found ) {
  256.     print STDERR "DEBUG: $progname: Driver '$driver' not in database!\n" if $debug;
  257.     }
  258.  
  259.     # Get all the data about this driver/printer pair
  260.     my $possible = $db->getdat($driver, $poid);
  261.     # Stop if the printer is not supported by the given driver
  262.     die "ERROR: $progname: That printer and driver combination is not possible.\n"
  263.     if (!$possible);
  264.     # Stop if the driver entry has an empty command line prototype or if there 
  265.     # is no custom PPD file
  266.     die "ERROR: $progname: There is neither a custom PPD file nor the driver database entry contains sufficient data to build a PPD file.\n"
  267.     if (!$db->{'dat'}{'cmd'}) && (!$db->{'dat'}{'ppdfile'});
  268.     
  269.     my @data;
  270.  
  271.     @data = $db->getppd($opt_w);
  272.     die "ERROR: $progname: No PPD file for printer '$poid' and driver '$driver'!\n"
  273.     if not @data;
  274.  
  275.     print @data;
  276.  
  277. }
  278.  
  279. sub help {
  280.     print <<HELP;
  281.  
  282. $progname -A
  283. $progname -P <regexpr>
  284. $progname -p <printerid> [-d <driver>] [-w]
  285. $progname list
  286. $progname cat <CUPS PPD URI> [-w]
  287. $progname -h
  288.  
  289.  -A             : show all Printer ID's and compatible drivers
  290.  -P <regexpr>   : show all Printer ID's whose names and model
  291.                   matched by the RE.  For example:
  292.                    -P HP will match all names with HP in them
  293.  -p <printerid> : Printer ID
  294.  -d <driver>    : Driver name
  295.                   If the driver is not specified then the default driver 
  296.                   for the <printerid> is used.
  297.  list           : List all possible PPDs in the format needed by the
  298.                   cups-driverd
  299.  cat <CUPS PPD URI> : Generate PPD file appropriate to the <CUPS PPD URI>.
  300.                   Available CUPS PPD URIs are listed by 
  301.                   "$progname list".
  302.  -w             : Generate PPD which is compatible with the CUPS PostScript
  303.                   driver for Windows (GUI strings are limited to 39 
  304.                   characters).
  305.  -h             : show help information
  306.  
  307.  
  308. HELP
  309.     exit 1;
  310.  
  311. }
  312.